package fr.sedoo.metadata.client.ui.widget.field.impl.keyword;

import java.util.ArrayList;
import java.util.Iterator;

import com.google.gwt.core.shared.GWT;

import fr.sedoo.commons.client.callback.LoadCallBack;
import fr.sedoo.commons.client.event.ActionEventConstants;
import fr.sedoo.commons.client.event.ActionStartEvent;
import fr.sedoo.commons.client.message.CommonMessages;
import fr.sedoo.commons.client.mvp.BasicClientFactory;
import fr.sedoo.commons.client.service.DefaultAbstractCallBack;
import fr.sedoo.commons.client.util.LocaleUtil;
import fr.sedoo.metadata.client.service.ThesaurusService;
import fr.sedoo.metadata.client.service.ThesaurusServiceAsync;
import fr.sedoo.metadata.shared.domain.thesaurus.SingleLevelThesaurus;
import fr.sedoo.metadata.shared.domain.thesaurus.Thesaurus;
import fr.sedoo.metadata.shared.domain.thesaurus.ThesaurusItem;

public class ClientThesaurusList {

	private static final ThesaurusServiceAsync THESAURUS_SERVICE = GWT.create(ThesaurusService.class);

	private static ArrayList<Thesaurus> thesauri;
	private static ArrayList<LoadCallBack> callBacks = new ArrayList<LoadCallBack>();
	private static boolean loaded = false;

	private static BasicClientFactory clientFactory;

	public static void setClientFactory(BasicClientFactory basicClientFactory) {
		ClientThesaurusList.clientFactory = basicClientFactory;
	}

	public static void getThesauri(LoadCallBack callBack) {
		if (loaded) {
			callBack.postLoadProcess(thesauri);
		} else {
			callBacks.add(callBack);
			loadThesauri();
		}
	}

	public static void getThesaurusItems(String thesaurusId, String language, LoadCallBack callBack) {
		Thesaurus thesaurusById = getThesaurusById(thesaurusId);
		if (thesaurusById == null) {
			// getThesauri(this);
		} else {
			loadItems(thesaurusById, language, callBack);
		}
	}

	private static void loadItems(Thesaurus thesaurus, String language, final LoadCallBack callBack) {
		if (thesaurus instanceof SingleLevelThesaurus) {
			final SingleLevelThesaurus aux = (SingleLevelThesaurus) thesaurus;
			ArrayList<ThesaurusItem> keywords = aux.getKeywords();
			if ((keywords == null) || (keywords.isEmpty())) {
				ActionStartEvent e = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstants.PARAMETER_LOADING_EVENT, true);
				clientFactory.getEventBus().fireEvent(e);
				THESAURUS_SERVICE.getItems(thesaurus.getId(), language, new DefaultAbstractCallBack<ArrayList<ThesaurusItem>>(e, clientFactory.getEventBus()) {

					@Override
					public void onSuccess(ArrayList<ThesaurusItem> result) {
						super.onSuccess(result);
						aux.setKeywords(result);
						callBack.postLoadProcess(result);
					}

				});
			} else {
				callBack.postLoadProcess(keywords);
			}
		}
	}

	private static void loadThesauri() {
		ActionStartEvent e = new ActionStartEvent(CommonMessages.INSTANCE.loading(), ActionEventConstants.PARAMETER_LOADING_EVENT, true);
		clientFactory.getEventBus().fireEvent(e);
		String language = LocaleUtil.getCurrentLanguage(clientFactory);
		THESAURUS_SERVICE.getThesaurus(language, new DefaultAbstractCallBack<ArrayList<Thesaurus>>(e, clientFactory.getEventBus()) {

			@Override
			public void onSuccess(ArrayList<Thesaurus> result) {
				super.onSuccess(result);
				thesauri = result;
				loaded = true;
				Iterator<LoadCallBack> iterator = callBacks.iterator();
				while (iterator.hasNext()) {
					getThesauri(iterator.next());
				}
				callBacks.clear();
			}

		});

	}

	public static Thesaurus getThesaurusById(String thesaurusId) {
		if (thesauri == null) {
			return null;
		} else {
			for (Thesaurus thesaurus : thesauri) {
				if (thesaurus.getId().compareTo(thesaurusId) == 0) {
					return thesaurus;
				}
			}
		}
		return null;
	}

}
